﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Timers;

namespace DataCodeDemo.Servers
{
    public class SocketTcpClient:SocketObject
    {
        private Socket client;
        private IPAddress _targetIp;
        private int _targetPort;
        private bool _isReConn;//重连
        private bool _isStop;//断开标志
        private System.Timers.Timer reConnTimer = new System.Timers.Timer(1000);

        public SocketTcpClient(bool isReConn = false)
        {
            _isReConn = isReConn;
            reConnTimer.Elapsed += ReConnTimer_Elapsed;
        }

        public override void InitSocket(IPAddress ip, int port)
        {
            _targetIp = ip;
            _targetPort = port;
        }

        public override void InitSocket(string ip, int port)
        {
            _targetIp = IPAddress.Parse(ip);
            _targetPort = port;
        }

        private void ReConnTimer_Elapsed(object sender, ElapsedEventArgs e)
        {
            ConnectToServer();
        }

        public override int Start()
        {
            if (client!=null&& client.Connected) return 1;
            if (reConnTimer.Enabled) return -1;
            _isStop = false;
            client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            return ConnectToServer();
        }

        private int ConnectToServer()
        {
            try
            {
                client.Connect(new IPEndPoint(_targetIp, _targetPort));
                reConnTimer.Enabled = false;
                Thread Recvth = new Thread(ReceiveMsg);
                Recvth.Start();
                return 1;
            }
            catch (Exception ex)
            {
                if (_isReConn && !reConnTimer.Enabled)
                {
                    reConnTimer.AutoReset = true;
                    reConnTimer.Enabled = true;
                }
                return -1;
            }
        }

        private void ReceiveMsg()
        {
            while (true)
            {
                if (_isStop) break;
                try
                {
                    byte[] buffer = new byte[1024 * 1024];
                    int n = client.Receive(buffer);
                    //string s = Encoding.UTF8.GetString(buffer, 0, n);
                    byte[] fromServerBytes = buffer.Take(n).ToArray();
                    InvokeRecvMsg(this, new RecvMsgEventArgs {
                        ClientSocket=client,
                        Msg=fromServerBytes
                    });
                    //client.Send(Encoding.UTF8.GetBytes("1" + Environment.NewLine));
                }
                catch (Exception ex)
                {
                    StopConnecte(client);
                    break;
                }
                Thread.Sleep(1);
            }
        }

        private void StopConnecte(Socket client)
        {
            try
            {
                if (client == null) return;
                if (client.Connected)
                {
                    client?.Shutdown(SocketShutdown.Both);
                    client?.Close(100);
                }
            }
            catch (Exception ex)
            {

            }
        }

        public override void Stop()
        {
            _isStop = true;
            reConnTimer.Enabled = false;
            StopConnecte(client);
        }

        public void Send(byte[] data)
        {
            try
            {
                if (client == null)
                {
                    return;
                }
                else
                {
                    if (!client.Connected)
                    {
                        client?.Close(100);
                    }
                    else
                    {
                        client.Send(data);
                    }
                }
            }
            catch (Exception ex)
            {

            }
        }

        
    }
}
